﻿#include "stdafx.h"
#include "LifeObject.h"
#include "Terrain.h"

LifeObject::LifeObject()
{
	m_requestMove = false;
	m_moveSpeed = 30;
	m_rotate = 0.0f;
	m_animPosOffset = 0.0f;
	m_fsm = nullptr;
    m_mapPos = { 0, 0 };
	m_mapDir = 0;
	memset(&m_animIndex, 0, sizeof(m_animIndex));
	m_dirTo = 0;
	m_requestDir = false;
	m_dirTo = 0;
	m_requestAttack = false;
	m_attackType = 0;
}


LifeObject::~LifeObject()
{
	if (m_fsm)
	{
		delete m_fsm;
		m_fsm = nullptr;
	}
}

void LifeObject::Update()
{
	SkeletonAnimation::Update();
	if (m_fsm) m_fsm->Update();
	//auto t = glm::translate(GetPosition());
	//auto r = glm::rotate(t, m_rotate, 0.0f, 0.0f, 1.0f);
	//auto s = glm::scale(r, glm::vec3(m_scale));
	//auto m = glm::translate(s, 0.0f, m_animPosOffset, 0.0f);
	//SetLocalMatrix(m);
	UpdateLocalMatrix();
}

void LifeObject::SetMapPos(POINT cell)
{
	m_mapPos = cell;
	if (m_cb_setMapPos) m_cb_setMapPos(cell);
}

POINT &LifeObject::GetMapPos()
{
	return m_mapPos;
}

void LifeObject::CalcMapPosition(POINT cell)
{
	SetMapPos(cell);
	SetPosition(cell.x * 100 + 50, cell.y * 100 + 50);
}

int LifeObject::GetAnimIndex_move()
{
	return m_animIndex.move;
}

int LifeObject::GetAnimIndex_idle()
{
	return m_animIndex.idle;
}

int LifeObject::CalcDir(POINT &pt1, POINT &pt2)
{
	static const int dir[3][3] = {
		{ 6, 5, 4 },
		{ 7, 1, 3 },
		{ 0, 1, 2 }
	};
	int x = pt2.x - pt1.x + 1;
	int y = pt2.y - pt1.y + 1;
	if (x < 0) x = 0;
	else if (x > 2) x = 2;
	if (y < 0) y = 0;
	else if (y > 2) y = 2;
	return dir[2 - y][x];
}

float LifeObject::Dir2Angle(int dir)
{
	static const float angle[] = { 315.0f, 0.0f, 45.0f, 90.0f, 135.0f, 180.0f, 225.0f, 270.0f };
	return angle[dir];
}

void LifeObject::SetDir(POINT pt)
{
	SetDir(CalcDir(m_mapPos, pt));
}

void LifeObject::SetDir(int dir)
{
	m_mapDir = dir;
	SetRotate(Dir2Angle(dir));
}

bool LifeObject::MakePath(POINT start, POINT end, std::list<POINT> &result)
{
	auto terr = Terrain::GetInstance();
	auto node = terr->m_maze.FindPath(start, end, true);
	result.clear();
	if (node)
	{
		terr->m_maze.MakePathList(node, result);
	}
	else
	{
		terr->m_maze.MakeNearPathList(result);
	}
	return result.size();
}

void LifeObject::PlayWalkSound()
{
	switch (m_lifeType)
	{
	case LifeObject::LifeType::me:
	{
		auto terr = Terrain::GetInstance();
		int idx = terr->GetTile1Index(m_mapPos.x, m_mapPos.y);
		switch (idx)
		{
		case 0:
		case 1:
			m_sound1.Play("./Data/Sound/pWalk(Grass).wav", 0, false);
			break;
		default:
			m_sound1.Play("./Data/Sound/pWalk(Soil).wav", 0, false);
			break;
		}
	}
	break;
	case LifeObject::LifeType::player:
		break;
	case LifeObject::LifeType::monster:
		break;
	case LifeObject::LifeType::npc:
		break;
	default:
		break;
	}

}

void LifeObject::MoveToMapPosition(int x, int y, int endDir)
{
	FSM::Move move;
	move.dirIdx = endDir;
	move.pt = { x,y };
	m_fsm->SetNextState_move(&move);
}

bool LifeObject::TestDistance()
{
	glm::vec2 p1(m_mapPos.x, m_mapPos.y);
	auto obj = (LifeObject*)m_target;
	auto &pt2 = obj->GetMapPos();
	glm::vec2 p2(pt2.x, pt2.y);
	p2 -= p1;
	auto len = glm::length(p2);
	return len <= m_allowDistance + m_radius + obj->m_radius;
}

void LifeObject::Attack(GameObject * target, int skill, float allowDistance)
{
	m_target = target;
	m_allowDistance = allowDistance;
	//m_fsm->st_attack
}

int LifeObject::GetSkillUseDistance(int skill)
{
	return 0;
}

int LifeObject::CalcTargetDistance(GameObject * target)
{
	auto obj = (LifeObject*)target;
	auto &pt1 = GetMapPos();
	auto &pt2 = obj->GetMapPos();
	glm::vec2 p1(pt1.x, pt1.y);
	glm::vec2 p2(pt2.x, pt2.y);
	p2 -= p1;
	auto len = glm::length(p2);
	return len;
}
